// lib/src/ui/calendar_grid.dart

import 'package:flutter/material.dart';
import 'package:omni_calendar_view/src/controller/omni_calendar_controller.dart';
import 'package:omni_calendar_view/src/models/calendar_day.dart';
import 'package:omni_calendar_view/src/utils/localization_util.dart';
import 'package:omni_calendar_view/src/utils/lunar_util.dart';

class CalendarGrid extends StatelessWidget {
  final DateTime month;
  final OmniCalendarController controller;
  final bool showSurroundingDays;
  final Locale locale;
  final Function(DateTime) onDateSelected;

  const CalendarGrid({
    super.key,
    required this.month,
    required this.controller,
    required this.showSurroundingDays,
    required this.locale,
    required this.onDateSelected,
  });

  @override
  Widget build(BuildContext context) {
    final localizations = OmniLocalizations(locale);
    final isLunarVisible = controller.showLunar && localizations.isChinese;

    return AnimatedBuilder(
      animation: controller,
      builder: (context, _) {
        final days = _generateMonthDays();
        return GridView.builder(
          physics: const NeverScrollableScrollPhysics(),
          shrinkWrap: true,
          gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
            crossAxisCount: 7,
            childAspectRatio: isLunarVisible ? 0.9 : 1,
          ),
          itemCount: days.length,
          itemBuilder: (context, index) {
            final day = days[index];
            if (!day.isCurrentMonth && !showSurroundingDays) {
              return const SizedBox.shrink();
            }
            return _buildDayCell(day, isLunarVisible);
          },
        );
      },
    );
  }


  Widget _buildDayCell(CalendarDay day, bool isLunarVisible) {
    final isToday = DateUtils.isSameDay(day.date, DateTime.now());

    // 1. 确定背景“轨道”的样式
    BoxDecoration? rangeDecoration;
    if (day.isStartDate || day.isInRange || day.isEndDate) {
      final color = Colors.blue.shade100;
      BorderRadius borderRadius;

      if (day.isStartDate && day.isEndDate) {
        // 单日范围，就是一个圆形
        borderRadius = BorderRadius.circular(100);
      } else if (day.isStartDate) {
        // 范围开始，左边是半圆
        borderRadius = const BorderRadius.horizontal(left: Radius.circular(120));
      } else if (day.isEndDate) {
        // 范围结束，右边是半圆
        borderRadius = const BorderRadius.horizontal(right: Radius.circular(120));
      } else {
        // 范围中间，是矩形
        borderRadius = BorderRadius.zero;
      }
      rangeDecoration = BoxDecoration(color: color, borderRadius: borderRadius);
    }

    // 确定文本颜色和样式
    Color textColor = day.isCurrentMonth ? Colors.black : Colors.grey.shade400;
    double fontSize = 14;
    FontWeight fontWeight = FontWeight.bold;

    if (day.isSelected) { // isSelected 为 true 代表是端点
      textColor = Colors.white;
      fontSize = 16;
    } else if (day.isInRange) {
      textColor = Colors.blue.shade800;
    } else if (isToday) {
      textColor = Colors.blue.shade300;
    }

    return GestureDetector(
      behavior: HitTestBehavior.opaque,
      onTap: () => onDateSelected(day.date),
      child: Stack(
        alignment: Alignment.center,
        children: [
          // 第一层：绘制连续的背景“轨道”
          if (rangeDecoration != null)
            Container(
              margin: const EdgeInsets.symmetric(vertical: 2 ,horizontal: 0),
              decoration: rangeDecoration,
            ),

          // 第二层：在端点上绘制深色的圆形背景
          if (day.isSelected)
           Container(
              decoration: BoxDecoration(
                color: Colors.blue.shade300,
                borderRadius: BorderRadius.circular(100), // 在正方形上应用，会变成完美的圆形
              ),
            ),

          // 第三层：放置文本内容
          Column(
            mainAxisAlignment: MainAxisAlignment.center,
            children: [
              Text(
                '${day.date.day}',
                style: TextStyle(
                  color: textColor,
                  fontSize: fontSize,
                  fontWeight: fontWeight,
                ),
              ),
              if (isLunarVisible && day.lunarDate.isNotEmpty)
                Padding(
                  padding: const EdgeInsets.only(top: 2.0),
                  child: Text(
                    day.lunarDate,
                    style: TextStyle(
                      fontSize: 10,
                      color: day.isInRange || day.isSelected
                          ? textColor.withOpacity(0.8)
                          : (day.isCurrentMonth
                          ? Colors.grey.shade600
                          : Colors.grey.shade400),
                    ),
                  ),
                ),
            ],
          ),
        ],
      ),
    );
  }

  List<CalendarDay> _generateMonthDays() {
    final List<CalendarDay> days = [];
    final firstDayOfMonth = DateTime(month.year, month.month, 1);

    final firstWeekday = firstDayOfMonth.weekday % 7;
    final startDate = firstDayOfMonth.subtract(Duration(days: firstWeekday));

    for (int i = 0; i < 42; i++) {
      final date = startDate.add(Duration(days: i));
      final isCurrentMonth = date.month == month.month;

      final day = CalendarDay(
        date: date,
        isCurrentMonth: isCurrentMonth,
        lunarDate: LunarUtil.getLunarDayString(date),
      );

      if (controller.selectionType == SelectionType.single && controller.selectedDate != null) {
        day.isSelected = DateUtils.isSameDay(date, controller.selectedDate);
      } else if (controller.selectionType == SelectionType.range && controller.selectedDateRange != null) {
        final range = controller.selectedDateRange!;
        day.isStartDate = DateUtils.isSameDay(date, range.start);
        day.isEndDate = DateUtils.isSameDay(date, range.end);
        day.isInRange = (date.isAfter(range.start) && date.isBefore(range.end)) ||
            DateUtils.isSameDay(date, range.start) ||
            DateUtils.isSameDay(date, range.end);
        day.isSelected = day.isStartDate || day.isEndDate;

        day.isInRange = date.isAfter(range.start) && date.isBefore(range.end);
      }

      days.add(day);
    }
    return days;
  }
}
